﻿using System;
using System.Collections.Generic;
using System.Data;
using accesoDatos;
using clasesBase;

namespace Logica
{
    public class ItemPlanificacionProduccion : EntidadAlmacenable
    {
        /* --------------------- Atributos de la clase. Recordar que hay atributos heredados --------------------- */
        private int idProducto = 0, cantidadCajas = 0, idPlanificacionProduccion = 0, ordenInterno = 0;
        private Producto objProducto;
        private bool prioridadAlta = false;

        private List<PlanillaProduccion> planillas;

        public const string tablaBD = "itemplanificacionproduccion", columnaID = "id";


        /* --------------------- Propiedades --------------------- */
        public int ID
        {
            get { return this.id; }
            set { this.id = value; }
        }

        public int CantidadCajas
        {
            get { return this.cantidadCajas; }
            set { this.cantidadCajas = value; }
        }

        public int OrdenInterno
        {
            get { return this.ordenInterno; }
            set { this.ordenInterno = value; }
        }

        public bool PrioridadAlta
        {
            get { return this.prioridadAlta; }
            set { this.prioridadAlta = value; }
        }

        public int IdPlanificacionProduccion
        {
            get { return this.idPlanificacionProduccion; }
            set { this.idPlanificacionProduccion = value; }
        }

        public Producto ObjProducto
        {
            get { return objProducto; }
            set
            {
                objProducto = value;
                this.idProducto = this.objProducto.ID;
            }
        }

        public List<PlanillaProduccion> Planillas
        {
            get { return this.planillas; }
            set { this.planillas = value; }
        }


        /* --------------------- Constructores --------------------- */
        public ItemPlanificacionProduccion()
            : this(0, true) // Llamo al constructor que recibe un parámetro para reutilizar el código del mismo
        { }

        public ItemPlanificacionProduccion(int idElem)
            : this(idElem, true) // Llamo al constructor que recibe un parámetro para reutilizar el código del mismo
        { }

        /* IMPORTANTE:
             ** Si el campo identificador unívoco de la tabla actual tuviese un nombre distinto de "id", se lo debe setear en este momento
             * (atributo heredado: nombreColumnaID)
             ** Si el campo identificador unívoco NO se generase automáticamente, se lo debe definir en este momento, cambiando el atributo
             * heredado idAutoGenerado por FALSE.
             */
        public ItemPlanificacionProduccion(int idElem, bool cargarLista)
            : base() // Llamo al constructor padre en primer lugar, para inicializar los valores correspondientes
        {
            // Es importante esta asignación ya que estos valores se utilizan tanto en métodos del objeto padre como éste
            this.nombreTablaBD = tablaBD;
            this.nombreColumnaID = columnaID;
            this.id = idElem;

            this.relacionesOtrasTablas.Add(PlanillaProduccion.tablaBD, "idItemPlanificacion");

            // Si se hubiese enviado un id != 0, entonces se buscan los datos del elemento en la BD para cargarlos al objeto actual que se está creando
            if (this.id != 0)
            {
                DataRow elemento = this.buscarElemento(id);
                try
                {
                    this.cantidadCajas = Convert.ToInt32(elemento["cantidad"]);
                    this.idProducto = Convert.ToInt32(elemento["idProducto"]);
                    this.idPlanificacionProduccion = Convert.ToInt32(elemento["idPlanificacionProduccion"]);
                    this.prioridadAlta = Convert.ToBoolean(elemento["prioridadAlta"]);
                    this.ordenInterno = Convert.ToInt32(elemento["ordenInterno"]);
                }
                catch (Exception ex)
                {
                    this.error = ex.Message;
                }
            }

            if (cargarLista) cargarColecciones();
            else
            {
                this.planillas = new List<PlanillaProduccion>();
            }

            this.objProducto = new Producto(this.idProducto, cargarLista);
        }

        public void cargarColecciones()
        {
            this.planillas = PlanillaProduccion.listar(new string[] { "idItemPlanificacion" }, new string[] { "E" + this.id.ToString() });
        }

        /* --------------------- Métodos --------------------- */
        public static List<ItemPlanificacionProduccion> listar(String[] columnasFiltros, String[] valoresFiltros)
        {
            List<ItemPlanificacionProduccion> listado = new List<ItemPlanificacionProduccion>();
            string[] orden = new string[] { "prioridadAlta DESC", "ordenInterno ASC" };
            DataTable tabla = EntidadAlmacenable.listarElementos(tablaBD, columnasFiltros, valoresFiltros, orden);
            try
            {
                foreach (DataRow fila in tabla.Rows)
                {
                    ItemPlanificacionProduccion elemento = new ItemPlanificacionProduccion(Convert.ToInt32(fila[columnaID]), true);
                    listado.Add(elemento);
                }
            }
            catch (Exception ex)
            {
            }

            return listado;
        }

        public static int proximoNumeroLote(int idProducto)
        {
            ManejadorBD manejadorBD = new ManejadorBD();

            string consultaSQL = string.Format("SELECT MAX(numeroLote) AS maximo FROM {1} join {0} on {1}.idItemPlanificacion = {0}.id WHERE {0}.idProducto = '{2}'",
                ItemPlanificacionProduccion.tablaBD, PlanillaProduccion.tablaBD, idProducto);
            int maximo = manejadorBD.obtenerNumeroEntero(consultaSQL);
            return maximo + 1;
        }

        public static int cantEstuchesTotales(int idItem)
        {
            ManejadorBD manejadorBD = new ManejadorBD();

            string consultaSQL = string.Format("SELECT SUM(cantEstuchesObtenidos) AS cantidad FROM {0} join {1} on {0}.idItemPlanificacion = {1}.id WHERE {1}.id = '{2}'",
                PlanillaProduccion.tablaBD, ItemPlanificacionProduccion.tablaBD, idItem);
            int cantidad = manejadorBD.contarRegistros(consultaSQL);
            return cantidad;
        }

        public String guardar()
        {
            String[] columnas = new String[] { columnaID, "cantidad", "idProducto", "idPlanificacionProduccion", "prioridadAlta", "ordenInterno" };
            String[] valores = new String[] { this.id.ToString(), this.cantidadCajas.ToString(), this.idProducto.ToString(), this.idPlanificacionProduccion.ToString(), Validador.formatearBool(this.prioridadAlta), this.ordenInterno.ToString() };

            string error = base.guardarElemento(columnas, valores);
            if (error.Equals("")) // Si se guardó correctamente el item, continúo y guardo las planillas
            {
                string errorPlanilla = "";
                foreach (PlanillaProduccion item in this.planillas)
                {
                    item.IdItemPlanificacionProduccion = this.id;
                    errorPlanilla = " " + item.guardar();
                }
                if (!errorPlanilla.Trim().Equals("")) error += "Errores ocurridos al insertar los ítems: " + errorPlanilla;
            }

            return error;
        }
    }
}